package solutions.ferpa.ztest.rest.action;

import br.com.telescope.adsrt.lib.AdsException;
import br.com.telescope.adsrt.lib.BaseRuntime;
import br.com.telescope.sql.Filter;
import solutions.ferpa.ztest.ent.EntClasseModelo;
import solutions.ferpa.ztest.ent.EntModeloHidrometro;
import solutions.ferpa.ztest.ent.EntVazaoPrefixoSerie;
import solutions.ferpa.ztest.rest.RestService;
import solutions.ferpa.ztest.rest.model.res.LoadProductRQ;
import solutions.ferpa.ztest.rest.model.res.LoadProductRS;

import javax.crypto.BadPaddingException;

@RestAction(action = "load_product", rqType = LoadProductRQ.class, rsType = LoadProductRS.class)
public class LoadProduct extends RestService<LoadProductRQ, LoadProductRS> {

    public LoadProduct(BaseRuntime ctx) {
        super(ctx);
    }

    private boolean validate(LoadProductRQ rq, LoadProductRS rs, EntModeloHidrometro product) throws AdsException {
        Filter filter;

        if (rq.getCode() == null || rq.getCode().isEmpty()) {
            rs.getAlerts().addError("O códgo do produto não foi informado.");
        } else {
            filter = new Filter();
            filter.equal(product.getCodigo(), rq.getCode());
            product.filterBy(filter);
            if (! product.next()) {
                product.nullify();
                product.nullifyId();
                product.setCodigo(rq.getCode());
            }
        }

        if (rq.getHorizontalClass() == null || rq.getHorizontalClass().isEmpty()) {
            rs.getAlerts().addError("A classe horizontal não foi informada.");
        } else {
            EntClasseModelo hClass = new EntClasseModelo(ctx);
            filter = new Filter();
            filter.equal(hClass.getCodigo(), rq.getHorizontalClass());
            hClass.filterBy(filter);
            if (hClass.next()) {
                product.setClasseHorizontalId(hClass.getId());
            } else {
                rs.getAlerts().addError("A classe horizontal informada não foi encontrada sistema.");
            }
            hClass.close();
        }

        if (rq.getVerticalClass() == null || rq.getVerticalClass().isEmpty()) {
            product.nullifyClasseVerticalId();
        } else {
            EntClasseModelo vClass = new EntClasseModelo(ctx);
            filter = new Filter();
            filter.equal(vClass.getCodigo(), rq.getVerticalClass());
            vClass.filterBy(filter);
            if (vClass.next()) {
                product.setClasseVerticalId(vClass.getId());
            } else {
                rs.getAlerts().addError("A classe vertical informada não foi encontrada no sistema.");
            }
            vClass.close();
        }

        if (rq.getHorizontalRatio() == null || rq.getHorizontalRatio().isEmpty()) {
            product.nullifyRazaoHorizontalId();
        } else {
            EntClasseModelo hRatio = new EntClasseModelo(ctx);
            filter = new Filter();
            filter.equal(hRatio.getCodigo(), rq.getHorizontalRatio());
            hRatio.filterBy(filter);
            if (hRatio.next()) {
                product.setRazaoHorizontalId(hRatio.getId());
            } else {
                rs.getAlerts().addError("A razão horizontal informada não foi encontrada sistema.");
            }
            hRatio.close();
        }

        if (rq.getVerticalRatio() == null || rq.getVerticalRatio().isEmpty()) {
            product.nullifyRazaoHorizontalId();
        } else {
            EntClasseModelo vRatio = new EntClasseModelo(ctx);
            filter = new Filter();
            filter.equal(vRatio.getCodigo(), rq.getVerticalRatio());
            vRatio.filterBy(filter);
            if (vRatio.next()) {
                product.setRazaoVerticalId(vRatio.getId());
            } else {
                rs.getAlerts().addError("A razão vertical informada não foi encontrada sistema.");
            }
            vRatio.close();
        }

        if (rq.getLength() <= 0) {
            rs.getAlerts().addError("O comprimento deve ser maior que zero.");
        } else {
            product.setComprimento(rq.getLength());
        }

        if (rq.getDescription() == null || rq.getDescription().isEmpty()) {
            rs.getAlerts().addError("A descrição do produto não foi informada.");
        } else {
            product.setDescricao(rq.getDescription());
        }

        if (rq.getDetailedDescription() == null || rq.getDetailedDescription().isEmpty()) {
            product.nullifyDescricaoDetalhada();
        } else {
            product.setDescricaoDetalhada(rq.getDetailedDescription());
        }

        if (rq.getNominalDiameter() <= 0) {
            rs.getAlerts().addError("O diâmetro nominal do produto não foi informado.");
        } else {
            product.setDiametroNominal(new Double(rq.getNominalDiameter()));
        }

        if (rq.getKFactor() == null || rq.getKFactor().doubleValue() <= 0) {
            product.nullifyFatorK();
        } else {
            product.setFatorK(rq.getKFactor());
        }

        if (rq.getMark() == null || rq.getMark().isEmpty()) {
            rs.getAlerts().addError("A marca do produto não foi informada.");
        } else {
            product.setMarca(rq.getMark());
        }

        if (rq.getSerialNumberPrefix() == null || rq.getSerialNumberPrefix().length() != 1) {
            rs.getAlerts().addError("O prefixo para o número de série não foi informado corretamente.");
        } else {
            if (rq.getNominalFlow() <= 0) {
                rs.getAlerts().addError("A vazão nominal deve ser maior que zero.");
            } else {
                EntVazaoPrefixoSerie nominalFlow = new EntVazaoPrefixoSerie(ctx);
                filter = new Filter();
                filter.equal(nominalFlow.getVazaoNominal(), new Double(rq.getNominalFlow() / 1000));
                nominalFlow.filterBy(filter);
                if (nominalFlow.next()) {
                    nominalFlow.setPrefixoNumeroSerie(rq.getSerialNumberPrefix());
                    nominalFlow.upd();
                } else {
                    nominalFlow.nullify();
                    nominalFlow.nullifyId();
                    nominalFlow.setPrefixoNumeroSerie(rq.getSerialNumberPrefix());
                    nominalFlow.setVazaoNominal(new Double(rq.getNominalFlow() / 1000));
                    nominalFlow.ins();
                }
                product.setVazaoPrefixoSerieId(nominalFlow.getId());
                nominalFlow.close();
            }

            if (rq.getPermanentFlow() <= 0) {
                rs.getAlerts().addError("A vazão permanente deve ser maior que zero.");
            } else {
                EntVazaoPrefixoSerie permanentFlow = new EntVazaoPrefixoSerie(ctx);
                filter = new Filter();
                filter.equal(permanentFlow.getVazaoNominal(), new Double(rq.getNominalFlow() / 1000));
                permanentFlow.filterBy(filter);
                if (permanentFlow.next()) {
                    permanentFlow.setPrefixoNumeroSerie(rq.getSerialNumberPrefix());
                    permanentFlow.upd();
                } else {
                    permanentFlow.nullify();
                    permanentFlow.nullifyId();
                    permanentFlow.setPrefixoNumeroSerie(rq.getSerialNumberPrefix());
                    permanentFlow.setVazaoNominal(new Double(rq.getNominalFlow() / 1000));
                    permanentFlow.ins();
                }
                product.setVazaoPermanenteId(permanentFlow.getId());
                permanentFlow.close();
            }
        }

        if (rq.getApprovalType() == null || rq.getApprovalType().isEmpty()) {
            product.nullifyPortariaAprovacao();
        } else {
            product.setPortariaAprovacao(rq.getApprovalType());
        }

        return (rs.getAlerts().hasErrors());
    }

    @Override
    public LoadProductRS call() throws Exception {
        LoadProductRQ rq = bindRequest(LoadProductRQ.class);
        LoadProductRS rs = new LoadProductRS();
        ctx.beginTransaction();
        EntModeloHidrometro product = new EntModeloHidrometro(ctx);

        if (validate(rq, rs, product)) {
            if (product.valueOfId() == null) {
                product.ins();
            } else {
                product.upd();
            }
            ctx.endTransaction();
            rs.setResource(Boolean.TRUE);
        } else {
            ctx.abortTransaction();
            rs.setResource(Boolean.FALSE);
        }

        product.close();

        return rs;
    }
}
